package com.amos.isearch.lucene;

import com.hankcs.lucene.HanLPIndexAnalyzer;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.MMapDirectory;
import org.apache.lucene.util.IOUtils;
import org.springframework.util.Assert;

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;

/**
 * 模块名称: ISearch
 * 模块描述: LuceneMainTest
 *
 * @author amos.wang
 * @date 2021/1/22 18:28
 */
public class LuceneMain {

    private static final String title = "美政客称中国制裁蓬佩奥“毫无根据”，华春莹回应";
    private static final String content = "根据美国相关机构的统计，特朗普政府执政期间，一共实施了3900多项不同的制裁措施，频率相当于每天三次，这些行径严重违反国际法和国际关系基本准则，严重损害相关国家的主权安全发展利益，不得人心，受到了国际社会的一致反对和谴责。";

    private static final Analyzer analyzer = new HanLPIndexAnalyzer();
    private static final Path indexPath = Path.of("DATA/index");

    private static volatile Directory directory;

    public static void main(String[] args) throws Exception {
        // 创建索引
        index();

        // 查询
        query();

        // 删除索引文件
        IOUtils.rm(indexPath);
        System.out.println("索引文件已删除");
    }

    /**
     * 创建索引
     */
    private static void index() throws Exception {
        // 3. 创建分词器配置
        IndexWriterConfig config = new IndexWriterConfig(analyzer);
        // 4. 创建输出流对象
        IndexWriter indexWriter = new IndexWriter(getDirectory(), config);

        Document doc = new Document();
        doc.add(new Field("title", title, TextField.TYPE_STORED));
        doc.add(new Field("content", content, TextField.TYPE_STORED));

        indexWriter.addDocument(doc);
        indexWriter.close();

        System.out.println("创建索引完成");
    }

    /**
     * 索引查询
     */
    private static void query() throws Exception {
        // Now search the index:
        DirectoryReader reader = DirectoryReader.open(getDirectory());
        IndexSearcher searcher = new IndexSearcher(reader);

        // Parse a simple query that searches for "中国制裁":
        QueryParser parser = new QueryParser("title", analyzer);
        Query query = parser.parse("中国制裁");
        ScoreDoc[] hits = searcher.search(query, 10).scoreDocs;

        Assert.isTrue(1 == hits.length, "搜索结果数量不匹配");
        System.out.println("搜索结果：" + Arrays.toString(hits));

        // Iterate through the results:
        for (ScoreDoc hit : hits) {
            Document hitDoc = searcher.doc(hit.doc);

            Assert.isTrue(title.equals(hitDoc.get("title")), "搜索结果不匹配");
            System.out.println("搜索结果详情：" + hitDoc);
        }

        reader.close();
        getDirectory().close();
    }

    /**
     * 创建 Directory 文件夹，对应索引库位置
     *
     * @return Directory
     * @throws Exception IOException
     */
    private static Directory getDirectory() throws Exception {
        if (directory == null) {
            synchronized (Directory.class) {
                if (directory == null) {
                    if (Files.notExists(indexPath)) {
                        Files.createDirectories(indexPath);
                    }

                    directory = MMapDirectory.open(indexPath);
                }
            }
        }

        return directory;
    }

}
